use core::num;
// 下面为自引用函数
use std::mem::drop;
use std::time::Instant;
use std::{sync::Mutex, time::Duration};
use std::thread::sleep;
use serialport::{SerialPort, ClearBuffer};

use tauri::{AppHandle, Emitter, Event, Listener};

//低能语言不这样写只能unsafe，想不到更好的用tauri的event系统收发消息的方法
static PORT: Mutex<Option<Box<dyn SerialPort>>> = Mutex::new(None);
static SEND_LISTEN_ID: Mutex<Option<u32>> = Mutex::new(None);

static BEFORE_STR_SPLIT: Mutex<String> = Mutex::new(String::new());

#[tauri::command]
pub async fn get_serial() -> Vec<String> {
  let ports = serialport::available_ports().expect("No ports found!");
  let mut result: Vec<String> = Vec::new();
  if !ports.is_empty(){
    for p in ports {
      result.push(p.port_name.clone());
    }
  }
  result
}

#[tauri::command]
pub async fn listen_serial(app: AppHandle, name: &str, baud_rate: &str) -> Result<String, String> {
  let u32_baud_rate:u32 = baud_rate.parse::<u32>()
    .map_err(|e| format!("baud_rate is not a u32 number, failed: {:?}", e))?;
  let mut port: Box<dyn SerialPort> = serialport::new(name, u32_baud_rate)
    .timeout(Duration::from_millis(10))
    .open()
    .map_err(|e| format!("Open port failed: {:?}", e))?;

  let mut port_guard = PORT.lock().unwrap();
  *port_guard = Some(port.try_clone().unwrap());


  //tauri的线程是基于tokio的轻量线程
  tauri::async_runtime::spawn(async move {
    let _ = send_serial_emit(app.clone());
    let _ = recv_serial_event(app.clone());//recv是在连接时是永远阻塞的，当*port_guard = None时，它下面的代码才会被执行。
  });
  Ok(format!("OK"))
}

#[tauri::command]
pub async fn close_serialport(app: AppHandle) -> Result<String, String> {
  let mut port_guard = PORT.lock().map_err(|e| format!("close_serialport failed: {:?}", e))?;
  *port_guard = None;

  let mut sl_id_guard = SEND_LISTEN_ID.lock().map_err(|e| format!("close_serialport failed: {:?}", e))?;
  let sl_id = match *sl_id_guard{
    Some(a) => a,
    None => {return Err(format!("sl_id_guard is none"))},
  };

  app.unlisten(sl_id);
  *sl_id_guard = None;
  
  Ok(format!("OK"))
}

pub fn send_serial(send_data: &str) -> Result<String, String> {
  let mut port_guard = PORT.lock().unwrap();
  let port = match port_guard.as_deref_mut(){
    Some(a) => a,
    None => {println!("send None");return Err(format!("port is none"))},
  };

  if port.bytes_to_write().map_err(|e| format!("port.bytes_to_write failed: {:?}", e))? == 0 {
    let output = send_data.as_bytes();
    port.write(output)
      .map_err(|e| format!("port.write failed: {:?}", e))?;
    Ok(format!("OK"))
  }else {
    port.clear(ClearBuffer::Output)
      .map_err(|e| format!("ClearBuffer::Output failed: {:?}", e))?;
    let output = send_data.as_bytes();
    port.write(output)
      .map_err(|e| format!("port.write failed: {:?}", e))?;
    Ok(format!("OK"))
  }
}

pub fn send_serial_emit(app: AppHandle) {
  let mut sl_id_guard = SEND_LISTEN_ID.lock().unwrap();
  let id = app.listen("send", |event| {
    //传递过来的字符串带""
    let send = event.payload().replace("\"", "");
    println!("send {}", send);
    let _ = send_serial(&send);
  });

  *sl_id_guard = Some(id);

}

pub fn recv_serial_event(app: AppHandle) -> Result<String, String> {
  let mut serial_buf: Vec<u8> = vec![0; 2048];

  let mut g_mo1: Vec<i32> = Vec::new();
  let mut g_mo2: Vec<i32> = Vec::new();
  let mut g_mo1_angle: Vec<f32> = Vec::new();
  let mut g_mo2_angle: Vec<f32> = Vec::new();
  let mut g_mo1_angle_rad: Vec<f32> = Vec::new();
  let mut g_mo2_angle_rad: Vec<f32> = Vec::new();
  let mut g_mo1_torque: Vec<f32> = Vec::new();
  let mut g_mo2_torque: Vec<f32> = Vec::new();

  let mut time = Instant::now();
  let duration = Duration::from_millis(250);

  loop {
    if time.elapsed() >= duration {

      let mut port_guard = PORT.lock().unwrap();
      let port = match port_guard.as_deref_mut(){
        Some(a) => a,
        None => {println!("recv None");return Err(format!("port is none"))},
      };

      if port.bytes_to_read().map_err(|e| format!("port.bytes_to_read failed: {:?}", e))? != 0 {
        let t = port.read(serial_buf.as_mut_slice()).unwrap();
        drop(port_guard); // 显式释放锁

        let data = &serial_buf[..t];
        match String::from_utf8(data.to_vec())
        {
          Ok(s) => {
            // sleep(Duration::from_millis(50));
            recv_str_split_avg(s, &mut g_mo1, &mut g_mo2, &mut g_mo1_angle, &mut g_mo2_angle, &mut g_mo1_angle_rad, &mut g_mo2_angle_rad, &mut g_mo1_torque, &mut g_mo2_torque);     
            // if time.elapsed() >= duration {
              let _ = app.emit("recv", recv_str(&mut g_mo1, &mut g_mo2, &mut g_mo1_angle, &mut g_mo2_angle, &mut g_mo1_angle_rad, &mut g_mo2_angle_rad, &mut g_mo1_torque, &mut g_mo2_torque));
              time = Instant::now();
            // }
            continue;},
          Err(e) => return Err(format!("Invalid UTF-8 sequence: {}", e)),
        }
      }

    }
  }
  //GBK//
  // let (cow, encoding_used, had_errors) = encoding_rs::GBK.decode(serial_buf.as_slice());
  // if had_errors {
  //     return format!("Decoding error");
  // } else {
  //   return format!("Decoded string: {}", cow);
  // }

  fn recv_str_split_avg(str: String, g_mo1: &mut Vec<i32>, g_mo2: &mut Vec<i32>, g_mo1_angle: &mut Vec<f32>, g_mo2_angle: &mut Vec<f32>, g_mo1_angle_rad: &mut Vec<f32>, g_mo2_angle_rad: &mut Vec<f32>, g_mo1_torque: &mut Vec<f32>, g_mo2_torque: &mut Vec<f32>) -> () {
    let mut num: usize = 0;
    let length: usize = 0;

    let mut mo1: i32 = 0;
    let mut mo2: i32 = 0;
    let mut mo1_angle:f32 = 0.0;
    let mut mo2_angle:f32 = 0.0;
    let mut mo1_angle_rad:f32 = 0.0;
    let mut mo2_angle_rad:f32 = 0.0;
    let mut mo1_num: usize = 0;
    let mut mo2_num: usize = 0;

    let mut mystr: String = String::new();

    let mut bss = BEFORE_STR_SPLIT.lock().unwrap();

    if *bss == "" {
      mystr = str;
    } else {
      mystr = bss.clone() + &str;
      *bss = String::from("");
    }

    let semicolon_parts: Vec<&str> = mystr.split(";").collect();
    *bss = semicolon_parts.last().unwrap_or(&"").to_string();
    drop(bss); // 显式释放锁
    let length = semicolon_parts.len();
    while num < length - 1 {
      // let blank_parts: Vec<&str> = semicolon_parts[num].split(" ").collect();

      // let mut parts_num: usize = 0;
      // let blank_length:usize = blank_parts.len();
      // while parts_num < blank_length {
      //   let blank_part:i32 = blank_parts[parts_num].parse::<i32>().expect("Failed to parse number");
      //   match parts_num {
      //       0 => mo1 = mo1 + blank_part as f64,
      //       1 => mo2 = mo2 + blank_part as f64,
      //       _ => ()
      //   };
      //   parts_num = parts_num + 1;
      // };
      if &semicolon_parts[num][0..1] == "a" {
        let now_mo1 = semicolon_parts[num][1..].parse::<i32>().expect("Failed to parse number");
        mo1 = mo1 + now_mo1;
        mo1_num = mo1_num + 1;
        g_mo1.push(now_mo1);
      }else if &semicolon_parts[num][0..1] == "b" {
        let now_mo2 = semicolon_parts[num][1..].parse::<i32>().expect("Failed to parse number");
        mo2 = mo2 + now_mo2;
        mo2_num = mo2_num + 1;
        g_mo2.push(now_mo2);
      }else if &semicolon_parts[num][0..1] == "u" {
        let now_mo1_torque = semicolon_parts[num][1..].parse::<f32>().expect("Failed to parse number");
        g_mo1_torque.push(now_mo1_torque);
      }else if &semicolon_parts[num][0..1] == "x" {
        let now_mo2_torque = semicolon_parts[num][1..].parse::<f32>().expect("Failed to parse number");
        g_mo2_torque.push(now_mo2_torque);
      }
      num = num + 1;

    }

    //你知道吗，除数不能为0。为0时会panic。
    if mo1_num != 0 {
      mo1 =  mo1 / mo1_num as i32;
      mo1_angle =  mo1 as f32 / 45.0;
      mo1_angle_rad = mo1_angle  / 57.2957
    }
    if mo2_num != 0 {
      mo2 =  mo2 / mo2_num as i32;   
      mo2_angle =  mo2 as f32 / 45.0;
      mo2_angle_rad = mo2_angle  / 57.2957
    }

    g_mo1_angle.push(mo1_angle);
    g_mo2_angle.push(mo2_angle);
    g_mo1_angle_rad.push(mo1_angle_rad);
    g_mo2_angle_rad.push(mo2_angle_rad);

    ()
  }
  
  fn recv_str(g_mo1: &mut Vec<i32>, g_mo2: &mut Vec<i32>, g_mo1_angle: &mut Vec<f32>, g_mo2_angle: &mut Vec<f32>, g_mo1_angle_rad: &mut Vec<f32>, g_mo2_angle_rad: &mut Vec<f32>, g_mo1_torque: &mut Vec<f32>, g_mo2_torque: &mut Vec<f32>) -> String {
    let mo1 = serde_json::to_string(&g_mo1).expect("serde_json::to_string failed");
    let mo2 = serde_json::to_string(&g_mo2).expect("serde_json::to_string failed");

    let mo1_angle = vec_avg(g_mo1_angle);
    let mo2_angle = vec_avg(g_mo2_angle);

    let mo1_angle_rad = vec_avg(g_mo1_angle_rad);
    let mo2_angle_rad = vec_avg(g_mo2_angle_rad);

    let mo1_torque = vec_avg(g_mo1_torque) / 100.0;//发上来的值是x100的
    let mo2_torque = vec_avg(g_mo2_torque) / 100.0;

    g_mo1.clear();
    g_mo2.clear();
    g_mo1_angle.clear();
    g_mo2_angle.clear();
    g_mo1_angle_rad.clear();
    g_mo2_angle_rad .clear();
    g_mo1_torque.clear();
    g_mo2_torque.clear();


    println!("recv_str run");

    return mo1 + " " + mo2.as_str() + " " + 
    mo1_angle.to_string().as_str() + " " + mo2_angle.to_string().as_str() + " " + 
    mo1_angle_rad.to_string().as_str() + " " + mo2_angle_rad.to_string().as_str() + " " + 
    mo1_torque.to_string().as_str() + " " + mo2_torque.to_string().as_str()
  }

  fn vec_avg(the_arr: &mut Vec<f32>) -> f32{
    let sum: f32 = the_arr.iter().sum();
    let count = the_arr.len() as f32;

    sum / count
  }

}
